package com.medic.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.medic.entity.group.pain.SikerInfo;
import com.medic.entity.group.pain.Task;
import com.medic.mapper.interf.SikerinfoMapper;
import com.medic.service.interf.SikerinfoServiceInterface;
import com.medic.util.CacheUtil;
import com.medic.util.StringUtil;

@Service("sikerinfoService")
@Transactional(readOnly = false, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) // 注明需要回滚
public class SikerinfoServiceImpl implements SikerinfoServiceInterface {

	@Autowired
	private SikerinfoMapper sikerinfoMapper;

	@Override
	public boolean save(SikerInfo object) throws Exception {
		boolean result = false;
		if (sikerinfoMapper.save(object) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public boolean delete(SikerInfo object) throws Exception {
		return false;
	}

	@Override
	public boolean update(SikerInfo object) throws Exception {
		boolean result = false;
		if (sikerinfoMapper.update(object) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public boolean endEvalById(int id) throws Exception {
		boolean result = false;
		if (sikerinfoMapper.endEvalById(id) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public boolean endEvalByUser(int sikerId, int groupId) throws Exception {
		boolean result = false;
		if (sikerinfoMapper.endEvalByUser(sikerId, groupId) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public List<SikerInfo> getAll() throws Exception {
		return sikerinfoMapper.selectAll();
	}

	@Scheduled(cron = "0 5 0 * * ?")
	@Override
	public void produceTask() throws Exception {
		int six = 360000;
		int day = 86400000;
		int hour = 3600000;
		long now = new Date().getTime();
		SikerInfo newInfo = null;
		for (Map.Entry<String, SikerInfo> entry : CacheUtil.getSikerinfos().entrySet()) {
			Task task = new Task();
			SikerInfo info = entry.getValue();
			newInfo = new SikerInfo();
			if (info.getIsTitr() > 1) {
				int tr = info.getIsTitr();
				if (info.getTrDate() - now <= six && tr == 3) {
					// 发微信消息，通知患者，进行疼痛评分，需要tsId
					// http://localhost:8080/Client/client/task/doTask?tsId=tsId
					// 疼痛评分完成后，需要马上发布服药任务（发威信消息提醒患者服药），并且将滴定titrNum加1
					// 而且将入组信息中的isTitr值设置为2，并修改任务中的过期时间为疼痛评分完成时间后1小时。
					// 在确认服药完成后，同样需要过期时间修改为服药完成时间后的2小时（服药完成后一小时评分），
					// 同时将入组信息中的trDate设置为服药完成时间后的1小时。

					// 设置两小时后，进行发布疼痛评价
					newInfo.setTrDate(info.getTrDate() + 2 * hour);
					info.setTrDate(info.getTrDate());
				}
			} else {
				if (info.getPainDate() - now < six) {
					task.setCrDate(info.getPainDate() + hour);
					task.setSikerId(info.getSikerId());
					task.setGroupId(info.getGroupId());
					task.setTsType(1);
					// 利用tsid发送微信消息，提醒患者做疼痛评估任务
					// http://localhost:8080/Client/client/task/doTask?tsId=tsId
					// (请求地址)

					// 定时任务中默认疼痛评分小于4，也就是说三天之后再发布任务，如果在完成疼痛评分的时候
					// 疼痛等级大于4，那么必须将改时间减去两天
					info.setPainDate(info.getPainDate() + 3 * day);
					newInfo.setPainDate(info.getPainDate());
				}
			}
			if (info.getRcDate() - now < six) {
				task.setCrDate(info.getRcDate() + day);
				task.setSikerId(info.getSikerId());
				task.setGroupId(info.getGroupId());
				task.setTsType(2);
				// 利用tsid发送微信消息，提醒患者做疼痛评估任务
				// http://localhost:8080/Client/client/task/doTask?tsId=tsId
				// (请求地址)

				info.setRcDate(info.getRcDate() + 3 * day);
				newInfo.setPainDate(info.getPainDate());
			}
			if (info.getCpDate() - now < six) {
				task.setCrDate(info.getCpDate() + 2 * day);
				task.setSikerId(info.getSikerId());
				task.setGroupId(info.getGroupId());
				task.setTsType(3);
				// 利用tsid发送微信消息，提醒患者做疼痛评估任务
				// http://localhost:8080/Client/client/task/doTask?tsId=tsId
				// (请求地址)

				info.setCpDate(info.getCpDate() + 15 * day);
				newInfo.setCpDate(info.getCpDate());
			}
			if (info.getHlDate() - now < six) {
				task.setCrDate(info.getHlDate() + 3 * day);
				task.setSikerId(info.getSikerId());
				task.setGroupId(info.getGroupId());
				task.setTsType(4);

				// 利用tsid发送微信消息，提醒患者做疼痛评估任务
				// http://localhost:8080/Client/client/task/doTask?tsId=tsId
				// (请求地址)

				info.setHlDate(info.getHlDate() + 15 * day);
				newInfo.setHlDate(info.getHlDate());
			}
			newInfo.setId(info.getId());
			sikerinfoMapper.update(newInfo);
		}
	}

	@Override
	public boolean updateCoPain(int id, int coPain) throws Exception {
		boolean result = false;
		if (sikerinfoMapper.updateCoPain(id, coPain) > 0) {
			result = true;
		}
		return result;
	}

	@Override
	public void initInfo(int sikerId, int groupId) throws Exception {
		SikerInfo info = CacheUtil.getSikerinfos().get(sikerId + "" + groupId);
		info.setStatus(1);
		long crDate = new Date().getTime();
		info.setCpDate(crDate + 15 * StringUtil.DAY);
		info.setHlDate(crDate + 30 * StringUtil.DAY);
		info.setPainDate(crDate + 3 * StringUtil.DAY);
		info.setRcDate(crDate + 3 * StringUtil.DAY);
		info.setTrDate(crDate + StringUtil.HOUR);
		SikerInfo newInfo = new SikerInfo();
		newInfo.setId(info.getId());
		newInfo.setCpDate(info.getCpDate());
		newInfo.setHlDate(info.getHlDate());
		newInfo.setPainDate(info.getPainDate());
		newInfo.setRcDate(info.getRcDate());
		newInfo.setTrDate(info.getTrDate());
		sikerinfoMapper.update(newInfo);
	}

	@Override
	public boolean restartInfo(int sikerId, int groupId) throws Exception {
		SikerInfo info = new SikerInfo();
		long now = new Date().getTime();
		// 重启流程后需要进行参数初始化
		info.setTrDate(now + StringUtil.HOUR);
		info.setPainDate(now + 3 * StringUtil.DAY);
		info.setRcDate(now + 3 * StringUtil.DAY);
		info.setCpDate(now + 15 * StringUtil.DAY);
		info.setHlDate(now + 30 * StringUtil.DAY);
		info.setSikerId(sikerId);
		info.setGroupId(groupId);
		if (sikerinfoMapper.restart(info) > 0) {
			// 初始化完成后，需要将准确信息查出来，并放入缓存
			info = sikerinfoMapper.selectByUser(sikerId, groupId);
			CacheUtil.getSikerinfos().put(sikerId + "" + groupId, info);
			return true;
		}
		return false;
	}

}
